package com.baturu.vin.hyundai.service.impl;

import com.baturu.carvin.dtos.CarTypeDTO;
import com.baturu.carvin.service.CarTypeService;
import com.baturu.carvin.service.impl.AppConfigLoader;
import com.baturu.kit.kit.guava2.Lists2;
import com.baturu.kit.kit.guava2.Sets2;
import com.baturu.vin.base.service.EPCVinWaitCacheService;
import com.baturu.vin.base.service.impl.SuperEPCAnalyser;
import com.baturu.vin.dto.EPCAnalyserEnum;
import com.baturu.vin.dto.EPCImagePointDTO;
import com.baturu.vin.dto.EPCPartsImageDTO;
import com.baturu.vin.dto.EPCPartsImagePositionDTO;
import com.baturu.vin.dto.superEPC.*;
import com.baturu.vin.dto.superEPC.entity.SEPCCarTypeQueryParam;
import com.baturu.vin.dto.superEPC.entity.SEPCGroupQueryParam;
import com.baturu.vin.dto.superEPC.entity.SEPCPartsQueryParam;
import com.baturu.vin.enums.LangEnum;
import com.baturu.vin.hyundai.constant.HyundaiKiaCommonConstant;
import com.baturu.vin.hyundai.dal.dao.*;
import com.baturu.vin.hyundai.dal.entity.HyundaiKiaFeatureEntity;
import com.baturu.vin.hyundai.dal.entity.SEPCHyundaiSubGroupEntity;
import com.baturu.vin.hyundai.dto.HyundaiExtendDTO;
import com.baturu.vin.hyundai.dto.HyundaiKiaPartsMappingDTO;
import com.baturu.vin.hyundai.dto.HyundaiKiaVehicleDTO;
import com.baturu.vin.hyundai.dto.KiaPartsDTO;
import com.baturu.vin.hyundai.transformer.HyundaiKiaSEPCCarTypeTransformer;
import com.baturu.vin.hyundai.transformer.HyundaiKiaSEPCGroupTransformer;
import com.baturu.vin.hyundai.transformer.HyundaiKiaSEPCPartsTransformer;
import com.baturu.vin.hyundai.transformer.ListMapTransformers;
import com.baturu.vin.kit.StreamKit;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: chenjiahao
 * @Time: 2019/7/2
 */
@Slf4j
@Service("hyundaiKiaSuperEPCAnalyser")
public class HyundaiKiaSuperEPCAnalyser extends SuperEPCAnalyser {
    @Autowired
    private HyundaiKiaVehicleDAO vehicleDAO;
    @Autowired
    private HyundaiKiaFeatureDAO featureDAO;
    @Autowired
    private HyundaiGroupDAO hyundaiGroupDAO;
    @Autowired
    protected AppConfigLoader appConfigLoader;
    @Autowired
    private LJDVinSerivce ljdVinSerivce;
    @Autowired
    private HyundaiEPCAnalyser hyundaiEPCAnalyser;
    @Autowired
    private KiaPartsDAO kiaPartsDAO;
    @Autowired
    private HyundaiKiaCarAnalyser carAnalyser;
    @Autowired
    private HyundaiKiaPartsMappingDAO mappingDAO;
    @Autowired
    private EPCVinWaitCacheService epcVinCacheService;
    @Autowired
    private CarTypeService carTypeService;

    @Override
    protected List<SEPCCarTypeDTO> querySuperEPCCarTypeByVinCode(SEPCCarTypeQueryParam param) {
        HyundaiKiaVehicleDTO vehicle = vehicleDAO.findVehicle(param.getVinCode());
        if (vehicle == null) {
            log.info("现在起亚查询不出车型信息：{}", param.getVinCode());
            epcVinCacheService.addWaitCacheVinCode(EPCAnalyserEnum.HYUNDAI, param.getVinCode());
            return Collections.emptyList();
        }
        setOption(vehicle, param.getLang());
        setBtrIdAndCarSystem(vehicle);
        return Lists.newArrayList(HyundaiKiaSEPCCarTypeTransformer.VIN_INFO_TO_MULTI_HMODTYP_SEPC_CAR_TYPE.apply(vehicle));
    }

    private void setBtrIdAndCarSystem(HyundaiKiaVehicleDTO vehicle) {
        try {
            String btrId = carAnalyser.analysisBtrIdAndBuildCarType(vehicle);
            if (StringUtils.isBlank(btrId)) {
                return;
            }
            vehicle.setBtrId(btrId);
            List<CarTypeDTO> carType = carTypeService.findCarTypeByBtrIds(Lists.newArrayList(btrId));
            String carSystem = CollectionUtils.isEmpty(carType) ? vehicle.getModel() : carType.get(0).getCarSystem();
            vehicle.setCarSystem(carSystem);
        } catch (Exception e) {
            log.warn("获取btrid失败,vin:{},原因:{}", vehicle.getVinCode(), e.toString());
        }
    }

    private void setOption(HyundaiKiaVehicleDTO vehicle, String lang) {
        List<HyundaiKiaFeatureEntity> featureCodesJson = vehicle.getFeatureCodesJson();
        if (CollectionUtils.isEmpty(featureCodesJson)) {
            return;
        }
        List<HyundaiKiaFeatureEntity> hyundaiKiaFeatureEntities = getFeatureEntity(featureCodesJson, lang);

        Map<String, String> mesGroupByLongCode = hyundaiKiaFeatureEntities.stream()
                .collect(Collectors.toMap(d -> d.getModel() + " " + d.getCode(),
                        HyundaiKiaFeatureEntity::getMessage,
                        (v1, v2) -> v1));
        vehicle.setOptionMap(mesGroupByLongCode);
    }

    private List<HyundaiKiaFeatureEntity> getFeatureEntity(List<HyundaiKiaFeatureEntity> featureCodesJson, String lang) {
        Set<String> codes = featureCodesJson.stream().map(HyundaiKiaFeatureEntity::getCode).collect(Collectors.toSet());
        return StreamKit.partitionStream(codes, HyundaiKiaCommonConstant.SEGMENT_QUERY_SIZE)
                .flatMap(l -> featureDAO.queryByCode(l, lang).stream())
                .collect(Collectors.toList());
    }

    @Override
    protected List<SEPCGroupDTO> queryGroupByVinCodeAndParentGroup(SEPCGroupQueryParam param) {
        SEPCGroupDTO mainGroupDTO = param.getGroupDTO();
        if (Objects.isNull(mainGroupDTO)) {
            return hyundaiGroupDAO.queryMainGroup(param.getLang());
        }
        return querySubGroupInfo(param);
    }

    private List<SEPCGroupDTO> querySubGroupInfo(SEPCGroupQueryParam param) {
        SEPCCarTypeDTO superCarTypeDTO = param.getSuperCarTypeDTO();
        if (Objects.isNull(param.getGroupDTO())
                || StringUtils.isBlank(param.getGroupDTO().getMainGroup())
                || Objects.isNull(superCarTypeDTO)) {
            return Collections.emptyList();
        }
        Map<String, String> extendMap = getExtendAttrMap(superCarTypeDTO);
        if (MapUtils.isEmpty(extendMap)) {
            return Collections.emptyList();
        }
        List<SEPCGroupDTO> sepcGroupDTOS = doQuerySubGroup(param.getVinCode(), param.getGroupDTO().getMainGroup(), extendMap, param.getLang());
        sepcGroupDTOS.forEach(d -> {
            d.setImageUrl(getBaseUrl() + StringUtils.replace(d.getImageUrl().replaceFirst("/", ""), ".gif", ""));
            d.setSubGroup(d.getSubGroupCode() + " " + d.getSubGroup());
            //test
            d.setSubGroupCode(d.getEpcPartsImageDTOList().get(0).getImageCode());
        });
        return sepcGroupDTOS;
    }

    private Map<String, String> getExtendAttrMap(SEPCCarTypeDTO superCarTypeDTO) {
        List<SEPCExtendAttributeDTO> extendAttrDTOs = superCarTypeDTO.getExtendAttrDTOs();
        if (CollectionUtils.isEmpty(superCarTypeDTO.getExtendAttrDTOs())) {
            return Collections.emptyMap();
        }
        return extendAttrDTOs.stream()
                .collect(Collectors.toMap(SEPCExtendAttributeDTO::getCode, d -> d.getValue().toString(), (v1, v2) -> v1));
    }

    private String getBaseUrl() {
        return appConfigLoader.getPartsPicBaseUrl();
    }

    private List<SEPCGroupDTO> doQuerySubGroup(String vinCode, String mainGroup, Map<String, String> extendMap, String lang) {
        List<SEPCHyundaiSubGroupEntity> sepcHyundaiSubGroupEntities = getSubGroup(vinCode, mainGroup, extendMap, lang);
        if (CollectionUtils.isEmpty(sepcHyundaiSubGroupEntities)) {
            return Collections.emptyList();
        }
        Map<String, List<SEPCHyundaiSubGroupEntity>> subGroupByCode = sepcHyundaiSubGroupEntities.stream().collect(Collectors.groupingBy(SEPCHyundaiSubGroupEntity::getGroupCode));
        return buildSEPCGroup(subGroupByCode);
    }

    private List<SEPCGroupDTO> buildSEPCGroup(Map<String, List<SEPCHyundaiSubGroupEntity>> subGroupByCode) {
        return subGroupByCode.entrySet().stream().map(d -> SEPCGroupDTO.builder()
                .subGroup(d.getValue().get(0).getGroupName())
                .subGroupCode(d.getKey())
                .imageUrl(d.getValue().get(0).getImageUrl())
                .epcPartsImageDTOList(buildImageCodes(d.getValue()))
                .build())
                .sorted(Comparator.comparing(SEPCGroupDTO::getSubGroupCode))
                .collect(Collectors.toList());
    }

    private List<EPCPartsImageDTO> buildImageCodes(List<SEPCHyundaiSubGroupEntity> subGroups) {
        return subGroups.stream().map(d -> {
            EPCPartsImageDTO epcPartsImageDTO = new EPCPartsImageDTO();
            epcPartsImageDTO.setImageCode(d.getGroupCode() + d.getImageX() + d.getImageY());
            return epcPartsImageDTO;
        }).distinct().collect(Collectors.toList());
    }

    private List<SEPCHyundaiSubGroupEntity> getSubGroup(String vinCode, String mainGroup, Map<String, String> extendMap, String lang) {
        List<SEPCHyundaiSubGroupEntity> kiaGroup = getKiaGroup(mainGroup, extendMap, lang);
        return CollectionUtils.isNotEmpty(kiaGroup)
                ? kiaGroup
                : getHyundaiGroup(vinCode, mainGroup, lang);
    }

    private List<SEPCHyundaiSubGroupEntity> getHyundaiGroup(String vinCode, String mainGroup, String lang) {
        HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO = hyundaiEPCAnalyser.analyseVinCode(vinCode);
        if (Objects.isNull(hyundaiKiaVehicleDTO)) {
            return Collections.emptyList();
        }
        List<KiaPartsDTO> partsDTOS = doGetHyundaiGroup(hyundaiKiaVehicleDTO, mainGroup, lang);
        if (CollectionUtils.isEmpty(partsDTOS)) {
            return Collections.emptyList();
        }
        hyundaiEPCAnalyser.filterGroup(partsDTOS, hyundaiKiaVehicleDTO);
        return getGroupByParts(partsDTOS);
    }

    private List<KiaPartsDTO> doGetHyundaiGroup(HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO, String mainGroup, String lang) {
        if (LangEnum.ZH.getLang().equals(lang)) {
            return hyundaiGroupDAO.queryHyundaiPartsBySubGroup(hyundaiKiaVehicleDTO, mainGroup);
        } else {
            return hyundaiGroupDAO.queryHyundaiPartsBySubGroupEn(hyundaiKiaVehicleDTO, mainGroup);
        }
    }

    private List<SEPCHyundaiSubGroupEntity> getGroupByParts(List<KiaPartsDTO> partsDTOS) {
        if (CollectionUtils.isEmpty(partsDTOS)) {
            return Collections.emptyList();
        }
        return partsDTOS.stream()
                .map(HyundaiKiaSEPCGroupTransformer.PARTS_TO_GROUP_ENTITY)
                .distinct()
                .collect(Collectors.toList());
    }

    private List<SEPCHyundaiSubGroupEntity> getKiaGroup(String mainGroup, Map<String, String> extendMap, String lang) {
        List<HyundaiExtendDTO> hyundaiExtendDTOS = ListMapTransformers.mapConvertToBean(Lists.newArrayList(extendMap), HyundaiExtendDTO.class);
        if (CollectionUtils.isEmpty(hyundaiExtendDTOS)) {
            return Collections.emptyList();
        }
        HyundaiExtendDTO hyundaiExtendDTO = hyundaiExtendDTOS.get(0);
        if (LangEnum.ZH.getLang().equals(lang)) {
            return hyundaiGroupDAO.queryKiaSubGroup(hyundaiExtendDTO, mainGroup);
        } else {
            return hyundaiGroupDAO.queryKiaSubGroupEn(hyundaiExtendDTO, mainGroup);
        }
    }

    @Override
    protected List<SEPCPartsDTO> queryPartsByVinCodeAndLastGroup(SEPCPartsQueryParam param) {
        String vinCode = param.getVinCode();
        SEPCGroupDTO groupDTO = param.getGroupDTO();
        if (StringUtils.isBlank(vinCode)
                || Objects.isNull(groupDTO)) {
            return Collections.emptyList();
        }
        HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO = hyundaiEPCAnalyser.analyseVinCode(vinCode);
        if (Objects.isNull(hyundaiKiaVehicleDTO)) {
            return Collections.emptyList();
        }
        List<KiaPartsDTO> kiaPartsDTOS = getPartsDTOsByGroupDto(groupDTO, hyundaiKiaVehicleDTO, param.getLang());
        return Lists2.transformNonNull(kiaPartsDTOS, HyundaiKiaSEPCPartsTransformer.HYUNDAI_KIA_PARTS_TO_SEPC_PARTS);
    }

    private List<KiaPartsDTO> getPartsDTOsByGroupDto(SEPCGroupDTO groupDTO, HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO, String lang) {
        List<KiaPartsDTO> partsDTOs = getPartsDTO(groupDTO, hyundaiKiaVehicleDTO, lang);
        if (CollectionUtils.isEmpty(partsDTOs)) {
            return Collections.emptyList();
        }
        return setAndDistinctPartsInfo(partsDTOs, hyundaiKiaVehicleDTO);
    }

    private List<KiaPartsDTO> getPartsDTO(SEPCGroupDTO groupDTO, HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO, String lang) {
        SEPCHyundaiSubGroupEntity sepcHyundaiSubGroupEntity = HyundaiKiaSEPCGroupTransformer.SEPC_GROUP_TO_HYUNDAI_KIA_GROUP.safeApply(groupDTO);
        List<KiaPartsDTO> kiaPartsDTOS = ljdVinSerivce.queryLJDPartsByGroup(sepcHyundaiSubGroupEntity, hyundaiKiaVehicleDTO, lang);
        return CollectionUtils.isNotEmpty(kiaPartsDTOS)
                ? kiaPartsDTOS
                : getHyundaiPartsByGroup(sepcHyundaiSubGroupEntity, hyundaiKiaVehicleDTO, lang);
    }

    private List<KiaPartsDTO> setAndDistinctPartsInfo(List<KiaPartsDTO> partsDTOs, HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO) {
        Map<String, String> btrPartsNameGroupByPartsCode = getBtrPartsNameMapping(partsDTOs, hyundaiKiaVehicleDTO.getBpno());
        Map<String, List<EPCPartsImagePositionDTO>> imageGroupByPartsCode = buildOnlinePartsImge(partsDTOs);
        partsDTOs = distinctParts(partsDTOs);
        partsDTOs.forEach(d -> {
            d.setFinalPartsImageUrl(getBaseUrl() + StringUtils.replace(d.getFinalPartsImageUrl().replaceFirst("/", ""), ".gif", ""));
            d.setBtrPartsName(btrPartsNameGroupByPartsCode.getOrDefault(d.getPartsId(), ""));
            d.setPartsImagePositionDTOS(imageGroupByPartsCode.getOrDefault(d.getFinalPartsCode(), Collections.emptyList()));
        });
        return partsDTOs;
    }

    private List<KiaPartsDTO> filterByCount(List<KiaPartsDTO> partsDTOs) {
        List<KiaPartsDTO> filterParts = partsDTOs.stream().filter(this::doFilterByCount).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(filterParts)) {
            return partsDTOs;
        }
        return filterParts;
    }

    private boolean doFilterByCount(KiaPartsDTO d) {
        return Integer.valueOf(d.getCount()) == d.getPartsImagePositionDTOS().size()
                || CollectionUtils.isEmpty(d.getPartsImagePositionDTOS());
    }

    private List<KiaPartsDTO> distinctParts(List<KiaPartsDTO> partsDTOs) {
        List<KiaPartsDTO> distinctParts = partsDTOs.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                        new TreeSet<>(Comparator.comparing(KiaPartsDTO::getPartsDistinctKey))), ArrayList::new));
        List<String> nonNullParts = distinctParts.stream()
                .filter(d -> Objects.nonNull(d.getCrnm()))
                .map(KiaPartsDTO::getFinalPartsCode)
                .collect(Collectors.toList());
        distinctParts.removeIf(d->filterNullParts(d,nonNullParts));
        return distinctParts;
    }

    private boolean filterNullParts(KiaPartsDTO d, List<String> nonNullParts) {
        return HyundaiKiaCommonConstant.Y.equals(d.getFilted()) && nonNullParts.contains(d.getFinalPartsCode());
    }

    private Map<String, List<EPCPartsImagePositionDTO>> buildOnlinePartsImge(List<KiaPartsDTO> partsDTOs) {
        return partsDTOs.stream().map(d -> {
            EPCPartsImagePositionDTO epcPartsImagePositionDTO = new EPCPartsImagePositionDTO();
            epcPartsImagePositionDTO.setPosition(d.getGroupNumber());
//            if (HyundaiKiaCommonConstant.Y.equals(d.getFilted())) {
//                epcPartsImagePositionDTO.setPartsCode(d.getFinalPartsCode() + HyundaiKiaCommonConstant.Y);
//            } else {
//                epcPartsImagePositionDTO.setPartsCode(d.getFinalPartsCode());
//            }
            epcPartsImagePositionDTO.setPartsCode(d.getFinalPartsCode());
            EPCImagePointDTO topLeft = new EPCImagePointDTO();
            topLeft.setX(compressImage(d.getFinalPartsImageX()));
            topLeft.setY(compressImage(d.getFinalPartsImageY()));
            EPCImagePointDTO bottomRight = new EPCImagePointDTO();
            bottomRight.setX(compressImage(d.getFinalPartsImageX() + d.getFinalPartsImageOffsetX()));
            bottomRight.setY(compressImage(d.getFinalPartsImageY() + d.getFinalPartsImageOffsetY()));
            epcPartsImagePositionDTO.setTopLeft(topLeft);
            epcPartsImagePositionDTO.setBottomRight(bottomRight);
            return epcPartsImagePositionDTO;
        }).distinct().collect(Collectors.groupingBy(EPCPartsImagePositionDTO::getPartsCode));
    }

    private Map<String, List<EPCPartsImagePositionDTO>> buildLBEPartsImge(List<KiaPartsDTO> partsDTOs) {
        return partsDTOs.stream().map(d -> {
            EPCPartsImagePositionDTO epcPartsImagePositionDTO = new EPCPartsImagePositionDTO();
            epcPartsImagePositionDTO.setPosition(d.getGroupNumber());
            epcPartsImagePositionDTO.setPartsCode(d.getFinalPartsCode());
            EPCImagePointDTO topLeft = new EPCImagePointDTO();
            topLeft.setX(d.getFinalPartsImageX());
            topLeft.setY(d.getFinalPartsImageY());
            EPCImagePointDTO bottomRight = new EPCImagePointDTO();
            bottomRight.setX(d.getFinalPartsImageX() + d.getFinalPartsImageOffsetX());
            bottomRight.setY(d.getFinalPartsImageY() + d.getFinalPartsImageOffsetY());
            epcPartsImagePositionDTO.setTopLeft(topLeft);
            epcPartsImagePositionDTO.setBottomRight(bottomRight);
            return epcPartsImagePositionDTO;
        }).distinct().collect(Collectors.groupingBy(EPCPartsImagePositionDTO::getPartsCode));
    }

    private Map<String, String> getBtrPartsNameMapping(List<KiaPartsDTO> partsDTOs, String bpno) {
        Set<String> partsIds = Sets2.transformNonNull(partsDTOs, KiaPartsDTO::getPartsId);
        List<HyundaiKiaPartsMappingDTO> hyundaiKiaPartsMappingDTOS = mappingDAO.queryByParts_id(bpno, partsIds);
        return hyundaiKiaPartsMappingDTOS.stream()
                .collect(Collectors.toMap(HyundaiKiaPartsMappingDTO::getPartsCode,
                        HyundaiKiaPartsMappingDTO::getPartsName,
                        (v1, v2) -> v1 + "," + v2));
    }

    private List<KiaPartsDTO> getHyundaiPartsByGroup(SEPCHyundaiSubGroupEntity sepcHyundaiSubGroupEntity, HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO, String lang) {
        if (Objects.isNull(sepcHyundaiSubGroupEntity)) {
            return Collections.emptyList();
        }
        List<KiaPartsDTO> kiaPartsDTOS = LangEnum.ZH.getLang().equals(lang)
                ? kiaPartsDAO.queryHyundaiPartsByGroup(sepcHyundaiSubGroupEntity, hyundaiKiaVehicleDTO)
                : kiaPartsDAO.queryHyundaiPartsByGroupEn(sepcHyundaiSubGroupEntity, hyundaiKiaVehicleDTO);
        hyundaiKiaVehicleDTO.setYiTianAnalysis(true);
        List<KiaPartsDTO> allParts = new ArrayList<>(kiaPartsDTOS);
        List<KiaPartsDTO> partsDTOS = hyundaiEPCAnalyser.filterPartsInfoByVinAnalyseResult(kiaPartsDTOS, hyundaiKiaVehicleDTO);
        addFiltedPartsHostPoints(allParts, partsDTOS);
        return partsDTOS;
    }

    private void addFiltedPartsHostPoints(List<KiaPartsDTO> allParts, List<KiaPartsDTO> partsDTOS) {
        if (CollectionUtils.isEmpty(allParts)) {
            return;
        }
        allParts.removeAll(partsDTOS);
        List<KiaPartsDTO> filtedPartsHP = Lists2.transformNonNull(allParts, HyundaiKiaSEPCPartsTransformer.BUILD_FILERD_PARTS_HOST_POINT);
        partsDTOS.addAll(filtedPartsHP);
    }

    private int compressImage(int position) {
        float p = position * HyundaiKiaCommonConstant.RATE;
        return (int) p;
    }

    @Override
    protected List<SEPCSearchPartsDTO> queryPartsByVinCodeAndParts(SEPCPartsQueryParam param) {
        String vinCode = param.getVinCode();
        SEPCPartsDTO partsDTO = param.getPartsDTO();
        if (StringUtils.isBlank(vinCode)
                || Objects.isNull(partsDTO)
                || StringUtils.isBlank(partsDTO.getPartsCode())) {
            return Collections.emptyList();
        }
        HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO = hyundaiEPCAnalyser.analyseVinCode(vinCode);
        if (Objects.isNull(hyundaiKiaVehicleDTO)) {
            return Collections.emptyList();
        }
        List<KiaPartsDTO> kiaPartsDTOS = getPartsDTOsByPartsCode(partsDTO.getPartsCode(), hyundaiKiaVehicleDTO, param.getLang());
        if (CollectionUtils.isEmpty(kiaPartsDTOS)) {
            return Collections.emptyList();
        }
        kiaPartsDTOS = setAndDistinctPartsInfo(kiaPartsDTOS, hyundaiKiaVehicleDTO);
        return Lists2.transformNonNull(kiaPartsDTOS, HyundaiKiaSEPCPartsTransformer.PARTS_TO_SEARCH_PARTS);
    }

    private List<KiaPartsDTO> getPartsDTOsByPartsCode(String partsCode, HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO, String lang) {
        return doGetPartsByPartsCodes(partsCode, hyundaiKiaVehicleDTO, lang)
                .stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                        new TreeSet<>(Comparator.comparing(KiaPartsDTO::getGroupDistinctKey))), ArrayList::new));
    }

    private List<KiaPartsDTO> doGetPartsByPartsCodes(String partsCode, HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO, String lang) {
        List<KiaPartsDTO> kiaPartsDTOS = ljdVinSerivce.queryLJDPartsByPreFix(partsCode, hyundaiKiaVehicleDTO, lang);
        return CollectionUtils.isNotEmpty(kiaPartsDTOS)
                ? kiaPartsDTOS
                : getHyundaiPartsByPartsCode(partsCode, hyundaiKiaVehicleDTO, lang);
    }

    private List<KiaPartsDTO> getHyundaiPartsByPartsCode(String partsCodes, HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO, String lang) {
        List<KiaPartsDTO> kiaPartsDTOS = LangEnum.ZH.getLang().equals(lang)
                ? kiaPartsDAO.queryByBpnoAndPartsCodeByPreFive(hyundaiKiaVehicleDTO.getBpno(), partsCodes)
                : kiaPartsDAO.queryByBpnoAndPartsCodeByPreFiveEn(hyundaiKiaVehicleDTO.getBpno(), partsCodes);
        hyundaiKiaVehicleDTO.setYiTianAnalysis(true);
        return hyundaiEPCAnalyser.filterPartsInfoByVinAnalyseResult(kiaPartsDTOS, hyundaiKiaVehicleDTO);
    }

    @Override
    protected List<SEPCSearchGroupDTO> queryGroupsByVinCodeAndParts(SEPCPartsQueryParam param) {
        String vinCode = param.getVinCode();
        SEPCPartsDTO partsDTO = param.getPartsDTO();
        if (StringUtils.isBlank(vinCode)
                || Objects.isNull(partsDTO)
                || StringUtils.isBlank(partsDTO.getPartsCode())) {
            return Collections.emptyList();
        }
        HyundaiKiaVehicleDTO hyundaiKiaVehicleDTO = hyundaiEPCAnalyser.analyseVinCode(vinCode);
        if (Objects.isNull(hyundaiKiaVehicleDTO)) {
            return Collections.emptyList();
        }
        List<KiaPartsDTO> kiaPartsDTOS = getPartsDTOsByPartsCode(partsDTO.getPartsCode(), hyundaiKiaVehicleDTO, param.getLang());
        if (CollectionUtils.isEmpty(kiaPartsDTOS)) {
            return Collections.emptyList();
        }
        return Lists2.transformNonNull(kiaPartsDTOS, HyundaiKiaSEPCGroupTransformer.PARTS_TO_SEARCH_GROUP);
    }

}
